#include "uefi.h"

// Author: you-call-this-a-project (foolish-shabby <2276316223@qq.com>)
// Just some POSIX wraps.
// 就一些 POSIX 包装

// 在 POSIX 包装底下的 nonposix.c 很矛盾不是么 =D

// 唉我就只支持ASCII了我不管了 反正OVMF也只支持到这
// 以下wchar_t与char的部分不是posix的

wchar_t c8towc(char c)
{
    return (wchar_t) c;
}

char wctoc8(wchar_t c)
{
    return (char) c;
}

void c8stowcs(const char *c8s, wchar_t *wcs)
{
    // 内存事宜由调用方决定 不关我事
    size_t len = strlen(c8s);
    for (int i = 0; i < len; i++) {
        wcs[i] = c8towc(c8s[i]);
    }
    wcs[len] = 0;
}

void wcstoc8s(const wchar_t *wcs, char *c8s)
{
    // 内存事宜由调用方决定 不关我事
    size_t len = 0;
    for (int i = 0; ; i++) {
        if (wcs[i] == 0) {
            len = i;
            break;
        }
    }
    for (int i = 0; i < len; i++) {
        c8s[i] = wctoc8(wcs[i]);
    }
    c8s[len] = 0;
}

void itoa(uint32_t value, char **buf_ptr_addr, uint8_t base)
{
    uint32_t m = value % base;
    uint32_t i = value / base;
    if (i) itoa(i, buf_ptr_addr, base);
    if (m < 10) {
        *((*buf_ptr_addr)++) = m + '0';
    } else {
        *((*buf_ptr_addr)++) = m - 10 + 'A';
    }
}

void printstring(char *s)
{
    for (; *s; s++) putchar(*s);
}

// getch 不是 POSIX 标准。POSIX 标准里与之行为相同的函数是 _getch，但我懒得单开一个文件

int getch(void)
{
    UINTN idx;
    gBS->WaitForEvent(1, &gST->ConIn->WaitForKey, &idx);
    EFI_INPUT_KEY key = {0};
    EFI_STATUS status = gST->ConIn->ReadKeyStroke(gST->ConIn, &key);
    int res = EFI_ERROR(status) ? 0 : key.UnicodeChar;
    if (res) putchar(res);
    return res;
}
